#include <iostream>
#include <fstream>
#include <string>
#include <queue>

class CSV {
public:
    // 需要传递一个CSV文件名，初始化的时候把文件的第一列作为数据读取
    CSV(const char* fileName) {
        using namespace std;
        tempNumberString = string("");
        char x;
        ifstream inputFileStream(fileName);
        while (true) {
            x = inputFileStream.get();
            if (inputFileStream.eof()) {
                try {
                    handleChar('\n');
                } catch (invalid_argument& e) {
                }
                break;
            } else {
                try {
                    handleChar(x);
                } catch (invalid_argument& e) {
                    break;
                }
            }
        }
        buildArrData();
    }
    ~CSV() {
        delete[] arrData;
    }
    long getSize() {
        return sizeOfArrData;
    }
    double& operator[](long i) {
        if (i >= sizeOfArrData) {
            return arrData[sizeOfArrData - 1];
        }
        if (i < 0) {
            return arrData[0];
        }
        return arrData[i];
    }
private:
    // 临时存储追加字符的字符串
    std::string tempNumberString;
    // 列数，从0开始
    long col = 0;
    // 行数，从0开始
    long row = 0;
    // 状态
    char stats = 0;
    // 队列
    std::queue<double> data;
    double* arrData;
    long sizeOfArrData = 0;
    // 处理从CSV中读取的一个个字符
    void handleChar(const char ch) {
        switch (stats) {
            case 0:
                doStatsZero(ch);
                break;
            case 1:
                doStatsOne(ch);
                break;
            default:
                std::cout << "Stats unknow" << std::endl;
        }
    }
    void doStatsZero(const char ch) {
        using namespace std;
        double result;
        if (',' != ch && '\r' != ch && '\n' != ch && '"' != ch) {
            tempNumberString += ch;
        }
        if (',' == ch) {
            col++;
            result = stod(tempNumberString);
            printNumber(result);
            tempNumberString.clear();
            stats = 1;
        }
        if ('\n' == ch) {
            col = 0;
            row++;
            result = stod(tempNumberString);
            printNumber(result);
            tempNumberString.clear();
        }
    }
    void doStatsOne(const char ch) {
        if (',' == ch) {
            col++;
        }
        if ('\n' == ch) {
            col = 0;
            row++;
            stats = 0;
        }
    }
    void printNumber(const double number) {
        data.push(number);
        sizeOfArrData++;
    }
    void buildArrData() {
        arrData = new double[sizeOfArrData];
        for (long i = 0; i < sizeOfArrData; i++) {
            arrData[i] = data.front();
            data.pop();
        }
    }
};
